﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IAdaptServiceExtensions.cs" company="">
//   
// </copyright>
// <summary>
//   The i adapt service extensions.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Libium.Adapters
{
    using System;

    /// <summary>
    ///   The i adapt service extensions.
    /// </summary>
    public static class IAdaptServiceExtensions
    {
        #region Public Methods and Operators

        /// <summary>
        /// The adapt.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <param name="obj">
        /// The obj. 
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="T"/> . 
        /// </returns>
        public static T Adapt<T>(this IAdaptService service, object obj)
        {
            return (T)service.Adapt(obj, typeof(T));
        }

        /// <summary>
        /// The adapt.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <param name="obj">
        /// The obj. 
        /// </param>
        /// <param name="type">
        /// The type. 
        /// </param>
        /// <returns>
        /// The <see cref="object"/> . 
        /// </returns>
        /// <exception cref="Exception">
        /// </exception>
        public static object Adapt(this IAdaptService service, object obj, Type type)
        {
            object result;
            if (!service.TryAdapt(obj, type, out result))
            {
                // Use typed exception
                throw new Exception("Can't adapt object of type " + obj.GetType().Name + " to type " + type.Name);
            }

            return result;
        }

        /// <summary>
        /// The can adapt.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <typeparam name="T1">
        /// </typeparam>
        /// <typeparam name="T2">
        /// </typeparam>
        /// <returns>
        /// The <see cref="bool"/> . 
        /// </returns>
        public static bool CanAdapt<T1, T2>(this IAdaptService service)
        {
            return service.CanAdapt(typeof(T1), typeof(T2));
        }

        /// <summary>
        /// The can adapt.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <param name="obj">
        /// The obj. 
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="bool"/> . 
        /// </returns>
        public static bool CanAdapt<T>(this IAdaptService service, object obj)
        {
            return CanAdapt(service, obj, typeof(T));
        }

        /// <summary>
        /// The can adapt.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <param name="obj">
        /// The obj. 
        /// </param>
        /// <param name="type">
        /// The type. 
        /// </param>
        /// <returns>
        /// The <see cref="bool"/> . 
        /// </returns>
        public static bool CanAdapt(this IAdaptService service, object obj, Type type)
        {
            return service.CanAdapt(obj.GetType(), type);
        }

        /// <summary>
        /// The try adapt.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <param name="obj1">
        /// The obj 1. 
        /// </param>
        /// <param name="obj2">
        /// The obj 2. 
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="bool"/> . 
        /// </returns>
        public static bool TryAdapt<T>(this IAdaptService service, object obj1, out T obj2)
        {
            object obj3;
            var result = service.TryAdapt(obj1, typeof(T), out obj3);
            obj2 = (T)obj3;
            return result;
        }

        #endregion
    }
}